package gupao.concurrency.simpledemo.simulate;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
public class BizEngine {

    @Value("${biz.pool.core_size:2}")
    private int coreSize;
    @Value("${biz.pool.max_size:2}")
    private int maxSize;

    private ThreadPoolExecutor bizThreadPoolService;

    @PostConstruct
    public void init(){
        log.info("BizEngine init: core pool size {} and max pool size {}", coreSize, maxSize);
        bizThreadPoolService = new ThreadPoolExecutor(coreSize, maxSize,
                0L,TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(1000),
                new SimpleThreadFactory("biz-thread-"));
    }

    public <T> Future<T> execute(Callable<T> task){
        return bizThreadPoolService.submit(task);
    }

    static class SimpleThreadFactory implements ThreadFactory {
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String prefix;

        public SimpleThreadFactory(String prefix) {
            this.prefix = prefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread( r,
                    prefix + threadNumber.getAndIncrement());
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);

            log.info("{} create sub thread {}", Thread.currentThread().getName(), t.getName());

            return t;
        }
    }
}
